/**
 * Copyright [2020] [LiBo/Alex of copyright liboware@gmail.com ]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package report.tools;

import lombok.Data;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.Optional;

/**
 * @project-name:lhy-report
 * @package-name:com.lhy.lhy.report.tools
 * @author:LiBo/Alex
 * @create-date:2021-09-16 22:41
 * @copyright:libo-alex4java
 * @email:liboware@gmail.com
 * @description:
 */
@Data
public abstract class AbstractDateRangeSplitter implements DateRangeSplitter{


    /**
     * 时间分片数量
     */
    private int splitNum;

    /**
     * 时间分片值
     */
    private long dateSplitValue;

    /**
     * 时间片的单位
     */
    private ChronoUnit dateSplitUnit;

    /**
     * 是否处于绝对分片机制
     * false为动态规划分片（动态平衡）
     */
    private boolean absolutely = Boolean.TRUE;


    /**
     * 构造器（通过每个分片的大小进行计算）
     * @param dateSplitUnit 时间分片单位
     * @param dateSplitValue 分片大小
     */
    public AbstractDateRangeSplitter(long dateSplitValue, ChronoUnit dateSplitUnit) {
        this.dateSplitValue = dateSplitValue;
        this.dateSplitUnit = dateSplitUnit;
    }


    /**
     * 构造器(通过分片数进行切片计算)
     * @param splitNum
     */
    public AbstractDateRangeSplitter(int splitNum) {
        this.splitNum = splitNum;
    }


    /**
     * 计算时间范围数值
     * @param startDate
     * @param endDate
     * @return
     */
    protected long computeTheDateDuration(LocalDateTime startDate, LocalDateTime endDate){
        Objects.requireNonNull(startDate,"startDate is not be null");
        Objects.requireNonNull(endDate,"endDate is not be null");
        dateSplitUnit = Optional.ofNullable(getDateSplitUnit()).orElse(ChronoUnit.DAYS);
        if(startDate.isAfter(endDate)){
            throw new IllegalArgumentException("startDate is not be after endDate!");
        }
        long dateRangeValue = getDateSplitUnit().between(startDate.toLocalDate(),endDate.toLocalDate());
        return dateRangeValue;
    }

}
